<template>
  <el-card
    class="dr-task wh-full ai-list-card !rounded-tl-16px !rounded-tr-16px overflow-hidden"
    body-class="task-card"
    :body-style="{ margin: 0, padding: 0, height: '100%', position: 'relative' }"
    shadow="never"
  >
    <template #header>
      视频任务
      <!-- TODO @fan：看看，怎么优化下这个样子哈。 -->
      <!-- <el-button @click="handleViewPublic">视频作品</el-button> -->
    </template>
    <!-- 视频列表 -->
    <el-scrollbar height="100%" class="w-full">
      <div class="task-video-list" ref="videoListRef">
        <VideoCard
          v-for="video in videoList"
          :key="video.id"
          :detail="video"
          @on-btn-click="handleVideoButtonClick"
          @on-mj-btn-click="handleVideoMidjourneyButtonClick"
          @preview-video="openVideoDialog"
        />
      </div>
    </el-scrollbar>
    <div class="task-video-pagination">
      <Pagination
        :pageSizes="[15, 20, 30, 50, 100]"
        :total="pageTotal"
        v-model:page="queryParams.pageNo"
        v-model:limit="queryParams.pageSize"
        @pagination="getVideoList"
      />
    </div>
  </el-card>

  <!-- 视频详情 -->
  <!-- <VideoDetail :show="isShowVideoDetail" :id="showVideoDetailId" @handle-drawer-close="handleDetailClose" /> -->
  <!-- 视频预览对话框 -->
  <el-dialog
    v-model="isVideoDialogVisible"
    title="视频预览"
    width="60%"
    center
    append-to-body
    top="10vh"
  >
    <div class="video-container">
      <video :src="videoUrl" controls autoplay> 您的浏览器不支持 video 标签。 </video>
    </div>
  </el-dialog>
</template>
<script setup lang="ts">
import { VideoApi, VideoVO } from '@/api/ai/video'
// import VideoDetail from './VideoDetail.vue'
import VideoCard from './VideoCard.vue'
import { ElLoading, LoadingOptionsResolved } from 'element-plus'
import { AiVideoStatusEnum } from '@/views/ai/utils/constants'
import download from '@/utils/download'

const message = useMessage() // 消息弹窗
const router = useRouter() // 路由

// 视频分页相关的参数
const queryParams = reactive({
  pageNo: 1,
  pageSize: 15
})
const pageTotal = ref<number>(0) // page size
const videoList = ref<VideoVO[]>([]) // video 列表
const videoListLoadingInstance = ref<any>() // video 列表是否正在加载中
const videoListRef = ref<any>() // ref
// 视频轮询相关的参数（正在生成中的）
const inProgressVideoMap = ref<{}>({}) // 监听的 video 映射，一般是生成中（需要轮询），key 为 video 编号，value 为 video
const inProgressTimer = ref<any>() // 生成中的 video 定时器，轮询生成进展
// 视频详情相关的参数
const isShowVideoDetail = ref<boolean>(false) // 视频详情是否展示
const showVideoDetailId = ref<number>(0) // 视频详情的视频编号

/** 处理查看发布的视频作品 */
const handleViewPublic = () => {
  router.push({
    name: 'AiVideoSquare'
  })
}
const isVideoDialogVisible = ref(false)
const videoUrl = ref('#')
const openVideoDialog = (url) => {
  isVideoDialogVisible.value = true
  videoUrl.value = url
}
/** 查看视频的详情  */
const handleDetailOpen = async () => {
  isShowVideoDetail.value = true
}

/** 关闭视频的详情  */
// const handleDetailClose = async () => {
//   isShowVideoDetail.value = false
// }

/** 获得 video 视频列表 */
const getVideoList = async () => {
  try {
    // 1. 加载视频列表
    videoListLoadingInstance.value = ElLoading.service({
      target: videoListRef.value,
      text: '加载中...'
    } as LoadingOptionsResolved)
    const { list, total } = await VideoApi.queryVideos(queryParams)
    videoList.value = list
    pageTotal.value = total

    // 2. 计算需要轮询的视频
    const newWatVideos = {}
    videoList.value.forEach((item) => {
      if (item.status === AiVideoStatusEnum.IN_PROGRESS) {
        newWatVideos[item.id] = item
      }
    })
    inProgressVideoMap.value = newWatVideos
  } finally {
    // 关闭正在“加载中”的 Loading
    if (videoListLoadingInstance.value) {
      videoListLoadingInstance.value.close()
      videoListLoadingInstance.value = null
    }
  }
}

/** 轮询生成中的 video 列表 */
const refreshWatchVideos = async () => {
  const videoIds = Object.keys(inProgressVideoMap.value).map(Number)
  console.log(videoIds, inProgressVideoMap.value, '---videoIds')

  if (videoIds.length == 0) {
    return
  }
  const list = await VideoApi.getVideoListMyByIds(videoIds)
  const newWatchVideos = {}
  list?.forEach((video) => {
    if (video.status === AiVideoStatusEnum.IN_PROGRESS) {
      newWatchVideos[video.id] = video
    } else {
      const index = videoList.value.findIndex((oldVideo) => video.id === oldVideo.id)
      if (index >= 0) {
        // 更新 videoList
        videoList.value[index] = video
      }
    }
  })
  inProgressVideoMap.value = newWatchVideos
}

/** 视频的点击事件 */
const handleVideoButtonClick = async (type: string, videoDetail: VideoVO) => {
  // 详情
  if (type === 'more') {
    showVideoDetailId.value = videoDetail.id
    await handleDetailOpen()
    return
  }
  // 删除
  if (type === 'delete') {
    await message.confirm(`是否删除该视频?`)
    await VideoApi.deleteVideoMy(videoDetail.id)
    await getVideoList()
    message.success('删除成功!')
    return
  }
  // 下载
  if (type === 'download') {
    await download.file(videoDetail.videoUrl)
    return
  }
  // 重新生成
  if (type === 'regeneration') {
    await emits('onRegeneration', videoDetail)
    return
  }
}

/** 处理 Midjourney 按钮点击事件  */
const handleVideoMidjourneyButtonClick = async (button: any, videoDetail: VideoVO) => {
  // 1. 构建 params 参数
  const data = {
    id: videoDetail.id,
    customId: button.customId
  } as any
  // 2. 发送 action
  // await VideoApi.midjourneyAction(data)
  // 3. 刷新列表
  await getVideoList()
}

defineExpose({ getVideoList }) // 暴露组件方法

const emits = defineEmits(['onRegeneration'])

/** 组件挂在的时候 */
onMounted(async () => {
  // 获取 video 列表
  await getVideoList()
  // 自动刷新 video 列表
  inProgressTimer.value = setInterval(async () => {
    await refreshWatchVideos()
  }, 1000 * 3)
})

/** 组件取消挂在的时候 */
onUnmounted(async () => {
  if (inProgressTimer.value) {
    clearInterval(inProgressTimer.value)
  }
})
</script>
<style lang="scss">
.dr-task {
  width: 100%;
  height: 100%;
}

.task-card {
  position: relative;
  height: 100%;
  padding: 0;
  margin: 0;
}

.task-video-list {
  position: relative;
  display: flex;
  height: 100%;
  padding: 0 20px 100px;
  background-color: #fff;
  box-sizing: border-box;

  /* 确保内边距不会增加高度 */
  flex-flow: row wrap;
  align-content: flex-start;
  gap: 12px;
}

.task-video-pagination {
  position: absolute;
  bottom: 44px;
  z-index: 999;
  display: flex;
  width: 100%;
  height: 50px;
  line-height: 90px;
  background-color: #fff;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}

.video-container {
  display: flex;
  justify-content: center;
  align-items: center;

  > video {
    width: 100%;
    max-height: 70vh;
    background-color: #000;
  }
}
</style>
<style lang="scss" scoped>
@import url('@/views/ai/image/index/components/index.scss');
</style>
